# 实现与商品相关的业务
from flask import Blueprint, render_template,request,flash,redirect,url_for,abort
from flask_login import login_required,current_user

from datetime import datetime
from app.models import db, Goods, Category, Message, Notification

# url_prefix---》url的前缀
bp=Blueprint('goods',__name__,url_prefix='/goods')

# http://localhost:5000/goods/publish
@bp.route("/publish",methods=['GET','POST'])
@login_required
def publish():
    if request.method=='POST':
        title=request.form.get('title')
        description = request.form.get('description')
        price = request.form.get('price')
        condition = request.form.get('condition')
        image_url = request.form.get('image_url')
        category_id = request.form.get('category_id')

        goods=Goods(title=title,
                    description=description,
                    price=price,
                    condition=condition,
                    image_url=image_url,
                    category_id=category_id,
                    seller_id=current_user.id,
                    create_time=datetime.utcnow())

        # 把商品信息插入到数据库中
        db.session.add(goods)
        db.session.commit()
        flash('物品发布成功')
        return redirect(url_for('index.index'))

    # select * from categories
    categories=Category.query.all()
    return render_template('publish.html',categories=categories);


# 查看商品详情的接口
# http://localhost:5000/goods/detail/1
@bp.route('/detail/<int:goods_id>')
def detail(goods_id):
    page=request.args.get('page',1,type=int)
    # 根据商品id，查询对应的商品
    # Goods.query.get(goods_id)
    goods=Goods.query.get_or_404(goods_id)

    # select * from message where goods_id=8
    # messages=(Message.query
    #           .filter_by(goods_id=goods_id)
    #           .order_by(Message.created_at.desc())
    #           .all())

    # 分页查询评论信息
    messages = (Message.query
                    .filter_by(goods_id=goods_id)
                    .order_by(Message.created_at.desc())
                    .paginate(page=page, per_page=5));
    # 如果是get请求，则直接跳到商品详情页
    return render_template('goods_detail.html',goods=goods,messages=messages)


# 实现商品留言
# # http://localhost:5000/goods/leave_message/1
@bp.route('/leave_message/<int:goods_id>',methods=['GET','POST'])
@login_required
def leave_message(goods_id):
    # 根据商品id，查找到对应的商品，给该商品留言
    #goods=Goods.query.get_or_404(goods_id)

    if request.method=='POST':
        # 实现留言功能
        content=request.form.get("content")
        if not content:
            flash("评论内容不能为空！")
        else:
            # 封装一个message对象---评论信息
            message=Message(content=content,
                            goods_id=goods_id,
                            user_id=current_user.id,
                            created_at=datetime.utcnow())

            db.session.add(message)

            goods = Goods.query.get_or_404(goods_id)
            # 保存留言信息
            notification = Notification(recipient_id=goods.seller_id,
                                        sender_id=current_user.id,
                                        message=f'{current_user.username} 在《{goods.title}》下留言：{content}')

            db.session.add(notification)

            db.session.commit()
            flash('留言成功')

        # 跳转到商品详情页
        return redirect(url_for('goods.detail',goods_id=goods_id))

    #return render_template('leave_message.html',goods=goods)


# 编辑商品
@bp.route('/edit/<int:goods_id>',methods=['GET','POST'])
@login_required
def edit_goods(goods_id):
    # 从数据库中根据id查询对应的商品
    goods=Goods.query.get_or_404(goods_id)
    # 只有商品的发布者，才有权限修改该商品
    if goods.seller_id!=current_user.id:
        # 1xx：表示当前正在建立连接；
        # 2xx: 200 ---》 浏览器请求成功；
        # 3xx: 302 ---> 表示重定向
        # 4xx: 400/401/402/403/404/405，客户端有问题
        # 5xx: 500 服务器端有错误；
        # 403状态码表示无权限
        abort(403)

    if request.method=='POST':
        goods.title=request.form.get('title')
        goods.description = request.form.get('description')
        goods.price = request.form.get('price')
        goods.condition = request.form.get('condition')
        goods.image_url = request.form.get('image_url')
        goods.category_id = request.form.get('category_id')
        # 提交事务
        db.session.commit()
        flash('商品更新成功')
        return redirect(url_for('goods.detail',goods_id=goods.id))

    categories=Category.query.all()
    return render_template('edit_goods.html',goods=goods,categories=categories)

# 删除商品
@bp.route('/delete/<int:goods_id>',methods=['POST'])
@login_required
def delete_goods(goods_id):
    goods=Goods.query.get_or_404(goods_id)
    if goods.seller_id!=current_user.id:
        abort(403)

    # 对于等待删除的商品而言，解决方案有3种：1.当时设计表的时候，表与表直接不涉及外键关系；
    # 2.利用sql语句进行级联删除；3.在代码层面，先删除评论表，再删商品表；
    # 注意；filter_by()函数要用关键字参数传参！
    messages=Message.query.filter_by(goods_id=goods_id).all()
    for message in messages:
        db.session.delete(message)

    # 执行删除
    db.session.delete(goods)
    db.session.commit()
    flash('删除成功')
    # 重定向到用户中心
    return  redirect(url_for('user_center.user_center'))


# 收藏
@bp.route('/favorite/<int:goods_id>')
@login_required
def favorite(goods_id):
    goods=Goods.query.get_or_404(goods_id)
    if goods not in current_user.favorites:
        # 在未收藏情况下，将该商品追加到收藏表中
        current_user.favorites.append(goods)
        db.session.commit()
        flash('收藏成功')
    return redirect(request.referrer or url_for('goods.detail',goods_id=goods.id))


# 取消收藏
@bp.route('/unfavorite/<int:goods_id>')
@login_required
def unfavorite(goods_id):
    goods=Goods.query.get_or_404(goods_id)
    if goods in current_user.favorites:
        # 在未收藏情况下，将该商品追加到收藏表中
        current_user.favorites.remove(goods)
        db.session.commit()
        flash('取消收藏')
    return redirect(request.referrer or url_for('goods.detail',goods_id=goods.id))

# 商品上架/下架函数--->切换商品的已售状态
@bp.route('/toggle_status/<int:goods_id>')
@login_required
def toggle_goods_status(goods_id):
    goods=Goods.query.get_or_404(goods_id)
    # 切换状态---取反
    goods.is_sold=not goods.is_sold
    db.session.commit()
    flash(f'商品「{goods.title}」已{"下架" if goods.is_sold else "上架"}')
    return redirect(url_for('user_center.user_center'))